﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Excel;

namespace BT2_XuLyDuLieu
{
    public partial class FormLoadData : Form
    {
            public FormLoadData()
        {
            InitializeComponent();
        }
        //------------------------------ Var --------------------------------------------------
        #region Var Define

        private string filePath = "";
        private string fileName;
        private string fileType;

        private string charSplit;
        private string missValue;
        private string[] headerStore;

        private bool[] isNumberic;
        private bool Header;
        private bool checker = false;

        private DataSet data;

        /// <summary>
        /// Properties
        /// </summary>
        public string FileName
        {
            get { return fileName; }
            set { fileName = value; }
        }

        public string FilePath{
            get { return filePath; }
            set { filePath = value; }
        }

        public DataSet Data
        {
            get { return data; }
            set { data = value; }
        }
        #endregion


        //------------------------------ User Function-----------------------------------------
        #region UserFunction

        /// <summary>
        /// Thiết lập các thông số trên giao diện khi form được load
        /// </summary>
        private void InitLoad()
        {
            // get file name
            string[] temp = filePath.Split('\\');
            fileName = temp[temp.Length - 1];

            // get file type
            fileType = fileName.Split('.')[1];
            
            switch (fileType)
            {
                case "csv": cbbDataType.SelectedIndex = 1; break;
                case "xlsx": cbbDataType.SelectedIndex = 2; break;
                case "xls": cbbDataType.SelectedIndex = 2; break;
                default: cbbDataType.SelectedIndex = 0; break;
            }

            txtDataFileName.Text = fileName;

            //bỏ phần mở rộng của file name (chút wa form kia ình xài têếp)
            fileName = fileName.Split('.')[0];

            txtMissingValue.Text = "?";
            txtEnclosure.Text = ";,";
            if (filePath.Equals(string.Empty))
            {
                MessageBox.Show("The Path of file is null, check again!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Close();
            }
        }

        /// <summary>
        /// Kiểm tra dữ liệu nâập khi người dùng bấm ok.
        /// </summary>
        /// <returns>Dữ liệu trả ra true nếu thực hiện được / false nếu không thành công.</returns>
        private bool InputChecker()
        {
            if (txtMissingValue.Text.Trim() == string.Empty)
            {
                txtMissingValue.Focus();
                MessageBox.Show("The Missing Value is empty, check again!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            if (txtEnclosure.Text.Trim() == string.Empty)
            {
                txtEnclosure.Focus();
                MessageBox.Show("The Enclosure value is empty, check again!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            return true;
        }

        /// <summary>
        /// Đưa dữ liệu mổi dòng được truyền vô vào dataset.
        /// </summary>
        /// <param name="str"></param>
        private void ConvertToDataset(string str)
        {
            //xóa đi mấy cái rườm rà.
            //str.Replace("\"", string.Empty);
            string[] temp = null;

            //cắt chuổi (giả xử nhập nhiều kiểu cắt) và lưu lại thằng dùng để cắt
            if (!checker)
            {
                for (int i = 0; i < charSplit.Length; i++)
                {
                    temp = str.Split(charSplit[i]);

                    if (temp.Count() != 1)
                    {
                        charSplit = charSplit[i].ToString();
                    }
                }
            }
            else
            {
                // khi checker == true -> âần chạy > 2. ta đã xát định được kí tự cắt nên không chạy dòng for lại.
                temp = str.Split((char)charSplit[0]);
            }

            // code xử lý ép về dataset
            if (Header && checker == false)
            {
                checker = true;
                isNumberic = new bool[temp.Count()];

                // nếu dòng đầu là header thì mình gán tên cột = header.
                for (int i = 0; i <= temp.GetUpperBound(0); i++)
                {
                    headerStore = temp;
                    isNumberic[i] = false;
                }

                return;
            }
            else if (Header == false && checker == false)
            {
                checker = true;
                isNumberic = new bool[temp.Count()];
                // nếu dòng âầu trong dữ liệu không phải là header thì mình lấy đại cái tên.
                for (int i = 0; i < temp.Count(); i++)
                {
                    if (temp[i].Contains("\""))
                    {
                        DataColumn dtc = data.Tables[0].Columns.Add(string.Format("Column {0}", i + 1), typeof(string));

                        dtc.AllowDBNull = true;
                        isNumberic[i] = false;
                    }
                    else
                    {
                        DataColumn dtc = data.Tables[0].Columns.Add(string.Format("Column {0}", i + 1), typeof(float));

                        dtc.AllowDBNull = true;
                        isNumberic[i] = true;

                    }
                    
                }
            }
            
            // đưa dữ liệu vào dataset.
            DataRow dr = data.Tables[0].NewRow();
            
            //đưa dữ liệu vào thành 1 hàng.
            for (int i = 0; i <= temp.GetUpperBound(0); i++)
            {
                if (checker && data.Tables[0].Rows.Count == 0)
                {
                    if (!temp[i].Contains("\""))
                    {
                        isNumberic[i] = true;

                        DataColumn cl = new DataColumn(headerStore[i].Replace("\"", "").Trim(), typeof(float));
                        cl.AllowDBNull = true;
                            
                        data.Tables[0].Columns.Add(cl);
                    }
                    else
                    {
                        DataColumn ct = new DataColumn(headerStore[i].Replace("\"", "").Trim(), typeof(string));
                        ct.AllowDBNull = true;
    
                        data.Tables[0].Columns.Add(ct);
                        
                    }
                }

                //xóa đi " của chuổi nếu có
                temp[i] = temp[i].Replace("\"", string.Empty);

                if (isNumberic[i])
                {
                    if (temp[i] != missValue)
                    {
                        dr[i] = float.Parse(temp[i].Trim());
                    }
                    //else
                    //    dr[i] = null;
                }
                else
                {
                    if (temp[i] != missValue)
                    {
                        dr[i] = temp[i].Trim();
                    }
                    //else
                    //    dr[i] = null;
                }
            }
            
            //thêm hàng dữ liệu vào data set.
            data.Tables[0].Rows.Add(dr);
        }

        /// <summary>
        /// Đọc file tù path (được main form truyền) lên.
        /// </summary>
        /// <returns></returns>
        private bool DocFile()
        {
            try
            {
                if (cbbDataType.SelectedIndex == 0 || cbbDataType.SelectedIndex == 1)
                {
                    // xử lý như text normal và csv file
                    FileStream fs = new FileStream(FilePath, FileMode.Open);
                    StreamReader reader = new StreamReader(fs);

                    data = new DataSet();
                    data.Tables.Add("TheData");


                    string rowString = reader.ReadLine();

                    while (rowString != null)
                    {
                        ConvertToDataset(rowString);

                        rowString = reader.ReadLine() ;
                    }

                    //Đóng tập tin
                    reader.Close();
                    //giải phóng vùng nhớ.
                    reader.Dispose();
                }

                if (cbbDataType.SelectedIndex == 2)
                {
                    // xử lí đọc file excel
                    FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                    IExcelDataReader excelReader;
                    
                    if (fileType == "xls")
                    {
                        //xử lý cho xls
                         excelReader = ExcelReaderFactory.CreateBinaryReader(fs);
                    }
                    else
                    {
                        // xử lý cho xlsx
                        excelReader = ExcelReaderFactory.CreateOpenXmlReader(fs);
                    }

                    excelReader.IsFirstRowAsColumnNames = Header;

                    //ép kiểu excel về dataset.
                    data = excelReader.AsDataSet();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            return true;
        }

        #endregion 


        //------------------------------ Visual Studio Generate Function --------------------------
        private void button1_Click(object sender, EventArgs e)
        {
            if (InputChecker())
            {
                // xét xem tập tin này có chưa header không.
                Header = rdoYes.Checked == true ? true : false;
                charSplit = txtEnclosure.Text;
                missValue = txtMissingValue.Text;

                DocFile();
                this.Close();
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void FormLoadData_Load(object sender, EventArgs e)
        {
            InitLoad();
        }

        private void cbbDataType_SelectedIndexChanged(object sender, EventArgs e)
        {
            int chois = cbbDataType.SelectedIndex;

            if (chois == 2)
                txtEnclosure.Enabled = false;
            else
                txtEnclosure.Enabled = true;
        }
    }
}
